﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;
using Newtonsoft.Json.Linq;

namespace IPC.Communication.Framework.BasicFramework
{
    public class SoftBasic
    {
        public static SystemVersion FrameworkVersion
        {
            get
            {
                return new SystemVersion("10.1.4");
            }
        }

        public static string CalculateFileMD5(string filePath)
        {
            string result = string.Empty;
            using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                result = SoftBasic.CalculateStreamMD5(fileStream);
            }
            return result;
        }

        public static string CalculateStreamMD5(Stream stream)
        {
            byte[] value = null;
            using (MD5 mD = new MD5CryptoServiceProvider())
            {
                value = mD.ComputeHash(stream);
            }
            return BitConverter.ToString(value).Replace("-", "");
        }

        public static string CalculateStreamMD5(string data)
        {
            return SoftBasic.CalculateStreamMD5(data, Encoding.UTF8);
        }

        public static string CalculateStreamMD5(string data, Encoding encode)
        {
            string result = string.Empty;
            using (MD5 mD = new MD5CryptoServiceProvider())
            {
                byte[] value = mD.ComputeHash(encode.GetBytes(data));
                result = BitConverter.ToString(value).Replace("-", "");
            }
            return result;
        }

        public static string GetSizeDescription(long size)
        {
            bool flag = size < 1000L;
            string result;
            if (flag)
            {
                result = size.ToString() + " B";
            }
            else
            {
                bool flag2 = size < 1000000L;
                if (flag2)
                {
                    result = ((float)size / 1024f).ToString("F2") + " Kb";
                }
                else
                {
                    bool flag3 = size < 1000000000L;
                    if (flag3)
                    {
                        result = ((float)size / 1024f / 1024f).ToString("F2") + " Mb";
                    }
                    else
                    {
                        result = ((float)size / 1024f / 1024f / 1024f).ToString("F2") + " Gb";
                    }
                }
            }
            return result;
        }

        public static string GetTimeSpanDescription(TimeSpan ts)
        {
            bool flag = ts.TotalSeconds <= 60.0;
            string result;
            if (flag)
            {
                result = ((int)ts.TotalSeconds).ToString() + StringResources.Language.TimeDescriptionSecond;
            }
            else
            {
                bool flag2 = ts.TotalMinutes <= 60.0;
                if (flag2)
                {
                    result = ts.TotalMinutes.ToString("F1") + StringResources.Language.TimeDescriptionMinute;
                }
                else
                {
                    bool flag3 = ts.TotalHours <= 24.0;
                    if (flag3)
                    {
                        result = ts.TotalHours.ToString("F2") + StringResources.Language.TimeDescriptionHour;
                    }
                    else
                    {
                        result = ts.TotalDays.ToString("F2") + StringResources.Language.TimeDescriptionDay;
                    }
                }
            }
            return result;
        }

        public static string ArrayFormat<T>(T[] array)
        {
            return SoftBasic.ArrayFormat<T>(array, string.Empty);
        }

        public static string ArrayFormat<T>(T[] array, string format)
        {
            bool flag = array == null;
            string result;
            if (flag)
            {
                result = "NULL";
            }
            else
            {
                StringBuilder stringBuilder = new StringBuilder("[");
                for (int i = 0; i < array.Length; i++)
                {
                    stringBuilder.Append(string.IsNullOrEmpty(format) ? array[i].ToString() : string.Format(format, array[i]));
                    bool flag2 = i != array.Length - 1;
                    if (flag2)
                    {
                        stringBuilder.Append(",");
                    }
                }
                stringBuilder.Append("]");
                result = stringBuilder.ToString();
            }
            return result;
        }

        public static string ArrayFormat<T>(T array)
        {
            return SoftBasic.ArrayFormat<T>(array, string.Empty);
        }

        public static string ArrayFormat<T>(T array, string format)
        {
            StringBuilder stringBuilder = new StringBuilder("[");
            Array array2 = array as Array;
            bool flag = array2 != null;
            if (flag)
            {
                foreach (object current in array2)
                {
                    stringBuilder.Append(string.IsNullOrEmpty(format) ? current.ToString() : string.Format(format, current));
                    stringBuilder.Append(",");
                }
                bool flag2 = array2.Length > 0 && stringBuilder[stringBuilder.Length - 1] == ',';
                if (flag2)
                {
                    stringBuilder.Remove(stringBuilder.Length - 1, 1);
                }
            }
            else
            {
                stringBuilder.Append(string.IsNullOrEmpty(format) ? array.ToString() : string.Format(format, array));
            }
            stringBuilder.Append("]");
            return stringBuilder.ToString();
        }

        public static void AddArrayData<T>(ref T[] array, T[] data, int max)
        {
            bool flag = data == null;
            if (!flag)
            {
                bool flag2 = data.Length == 0;
                if (!flag2)
                {
                    bool flag3 = array.Length == max;
                    if (flag3)
                    {
                        Array.Copy(array, data.Length, array, 0, array.Length - data.Length);
                        Array.Copy(data, 0, array, array.Length - data.Length, data.Length);
                    }
                    else
                    {
                        bool flag4 = array.Length + data.Length > max;
                        if (flag4)
                        {
                            T[] array2 = new T[max];
                            for (int i = 0; i < max - data.Length; i++)
                            {
                                array2[i] = array[i + (array.Length - max + data.Length)];
                            }
                            for (int j = 0; j < data.Length; j++)
                            {
                                array2[array2.Length - data.Length + j] = data[j];
                            }
                            array = array2;
                        }
                        else
                        {
                            T[] array3 = new T[array.Length + data.Length];
                            for (int k = 0; k < array.Length; k++)
                            {
                                array3[k] = array[k];
                            }
                            for (int l = 0; l < data.Length; l++)
                            {
                                array3[array3.Length - data.Length + l] = data[l];
                            }
                            array = array3;
                        }
                    }
                }
            }
        }

        public static T[] ArrayExpandToLength<T>(T[] data, int length)
        {
            bool flag = data == null;
            T[] result;
            if (flag)
            {
                result = new T[length];
            }
            else
            {
                bool flag2 = data.Length == length;
                if (flag2)
                {
                    result = data;
                }
                else
                {
                    T[] array = new T[length];
                    Array.Copy(data, array, Math.Min(data.Length, array.Length));
                    result = array;
                }
            }
            return result;
        }

        public static T[] ArrayExpandToLengthEven<T>(T[] data)
        {
            bool flag = data == null;
            T[] result;
            if (flag)
            {
                result = new T[0];
            }
            else
            {
                bool flag2 = data.Length % 2 == 1;
                if (flag2)
                {
                    result = SoftBasic.ArrayExpandToLength<T>(data, data.Length + 1);
                }
                else
                {
                    result = data;
                }
            }
            return result;
        }

        public static List<T[]> ArraySplitByLength<T>(T[] array, int length)
        {
            bool flag = array == null;
            List<T[]> result;
            if (flag)
            {
                result = new List<T[]>();
            }
            else
            {
                List<T[]> list = new List<T[]>();
                int i = 0;
                while (i < array.Length)
                {
                    bool flag2 = i + length < array.Length;
                    if (flag2)
                    {
                        T[] array2 = new T[length];
                        Array.Copy(array, i, array2, 0, length);
                        i += length;
                        list.Add(array2);
                    }
                    else
                    {
                        T[] array3 = new T[array.Length - i];
                        Array.Copy(array, i, array3, 0, array3.Length);
                        i += length;
                        list.Add(array3);
                    }
                }
                result = list;
            }
            return result;
        }

        public static int[] SplitIntegerToArray(int integer, int everyLength)
        {
            int[] array = new int[integer / everyLength + ((integer % everyLength == 0) ? 0 : 1)];
            for (int i = 0; i < array.Length; i++)
            {
                bool flag = i == array.Length - 1;
                if (flag)
                {
                    array[i] = ((integer % everyLength == 0) ? everyLength : (integer % everyLength));
                }
                else
                {
                    array[i] = everyLength;
                }
            }
            return array;
        }

        public static bool IsTwoBytesEquel(byte[] b1, int start1, byte[] b2, int start2, int length)
        {
            bool flag = b1 == null || b2 == null;
            bool result;
            if (flag)
            {
                result = false;
            }
            else
            {
                for (int i = 0; i < length; i++)
                {
                    bool flag2 = b1[i + start1] != b2[i + start2];
                    if (flag2)
                    {
                        result = false;
                        return result;
                    }
                }
                result = true;
            }
            return result;
        }

        public static bool IsTwoBytesEquel(byte[] b1, byte[] b2)
        {
            bool flag = b1 == null || b2 == null;
            bool result;
            if (flag)
            {
                result = false;
            }
            else
            {
                bool flag2 = b1.Length != b2.Length;
                result = (!flag2 && SoftBasic.IsTwoBytesEquel(b1, 0, b2, 0, b1.Length));
            }
            return result;
        }

        public static bool IsByteTokenEquel(byte[] head, Guid token)
        {
            return SoftBasic.IsTwoBytesEquel(head, 12, token.ToByteArray(), 0, 16);
        }

        public static bool IsTwoTokenEquel(Guid token1, Guid token2)
        {
            return SoftBasic.IsTwoBytesEquel(token1.ToByteArray(), 0, token2.ToByteArray(), 0, 16);
        }

        public static TEnum[] GetEnumValues<TEnum>() where TEnum : struct
        {
            return (TEnum[])Enum.GetValues(typeof(TEnum));
        }

        public static TEnum GetEnumFromString<TEnum>(string value) where TEnum : struct
        {
            return (TEnum)((object)Enum.Parse(typeof(TEnum), value));
        }

        public static T GetValueFromJsonObject<T>(JObject json, string name, T defaultValue)
        {
            bool flag = json.Property(name) != null;
            T result;
            if (flag)
            {
                result = Extensions.Value<T>(json.Property(name).Value);
            }
            else
            {
                result = defaultValue;
            }
            return result;
        }

        public static void JsonSetValue<T>(JObject json, string property, T value)
        {
            bool flag = json.Property(property) != null;
            if (flag)
            {
                json.Property(property).Value = new JValue(value);
            }
            else
            {
                json.Add(property, new JValue(value));
            }
        }

        public static void ShowExceptionMessage(Exception ex)
        {
            Console.WriteLine(SoftBasic.GetExceptionMessage(ex));
        }

        public static void ShowExceptionMessage(string extraMsg, Exception ex)
        {
            Console.WriteLine(SoftBasic.GetExceptionMessage(extraMsg, ex));
        }

        public static string GetExceptionMessage(Exception ex)
        {
            string[] expr_07 = new string[8];
            expr_07[0] = StringResources.Language.ExceptionMessage;
            expr_07[1] = ex.Message;
            expr_07[2] = Environment.NewLine;
            expr_07[3] = StringResources.Language.ExceptionStackTrace;
            expr_07[4] = ex.StackTrace;
            expr_07[5] = Environment.NewLine;
            expr_07[6] = StringResources.Language.ExceptionTargetSite;
            int arg_64_1 = 7;
            MethodBase expr_58 = ex.TargetSite;
            expr_07[arg_64_1] = ((expr_58 != null) ? expr_58.ToString() : null);
            return string.Concat(expr_07);
        }

        public static string GetExceptionMessage(string extraMsg, Exception ex)
        {
            bool flag = string.IsNullOrEmpty(extraMsg);
            string result;
            if (flag)
            {
                result = SoftBasic.GetExceptionMessage(ex);
            }
            else
            {
                result = extraMsg + Environment.NewLine + SoftBasic.GetExceptionMessage(ex);
            }
            return result;
        }

        public static string ByteToHexString(byte[] InBytes)
        {
            return SoftBasic.ByteToHexString(InBytes, '\0');
        }

        public static string ByteToHexString(byte[] InBytes, char segment)
        {
            return SoftBasic.ByteToHexString(InBytes, segment, 0);
        }

        public static string ByteToHexString(byte[] InBytes, char segment, int newLineCount)
        {
            bool flag = InBytes == null;
            string result;
            if (flag)
            {
                result = string.Empty;
            }
            else
            {
                StringBuilder stringBuilder = new StringBuilder();
                long num = 0L;
                for (int i = 0; i < InBytes.Length; i++)
                {
                    byte b = InBytes[i];
                    bool flag2 = segment == '\0';
                    if (flag2)
                    {
                        stringBuilder.Append(string.Format("{0:X2}", b));
                    }
                    else
                    {
                        stringBuilder.Append(string.Format("{0:X2}{1}", b, segment));
                    }
                    num += 1L;
                    bool flag3 = newLineCount > 0 && num >= (long)newLineCount;
                    if (flag3)
                    {
                        stringBuilder.Append(Environment.NewLine);
                        num = 0L;
                    }
                }
                bool flag4 = segment != '\0' && stringBuilder.Length > 1 && stringBuilder[stringBuilder.Length - 1] == segment;
                if (flag4)
                {
                    stringBuilder.Remove(stringBuilder.Length - 1, 1);
                }
                result = stringBuilder.ToString();
            }
            return result;
        }

        public static string ByteToHexString(string InString)
        {
            return SoftBasic.ByteToHexString(Encoding.Unicode.GetBytes(InString));
        }

        private static int GetHexCharIndex(char ch)
        {
            int result;
            switch (ch)
            {
                case '0':
                    result = 0;
                    return result;
                case '1':
                    result = 1;
                    return result;
                case '2':
                    result = 2;
                    return result;
                case '3':
                    result = 3;
                    return result;
                case '4':
                    result = 4;
                    return result;
                case '5':
                    result = 5;
                    return result;
                case '6':
                    result = 6;
                    return result;
                case '7':
                    result = 7;
                    return result;
                case '8':
                    result = 8;
                    return result;
                case '9':
                    result = 9;
                    return result;
                case ':':
                case ';':
                case '<':
                case '=':
                case '>':
                case '?':
                case '@':
                    goto IL_D6;
                case 'A':
                    break;
                case 'B':
                    goto IL_BD;
                case 'C':
                    goto IL_C2;
                case 'D':
                    goto IL_C7;
                case 'E':
                    goto IL_CC;
                case 'F':
                    goto IL_D1;
                default:
                    switch (ch)
                    {
                        case 'a':
                            break;
                        case 'b':
                            goto IL_BD;
                        case 'c':
                            goto IL_C2;
                        case 'd':
                            goto IL_C7;
                        case 'e':
                            goto IL_CC;
                        case 'f':
                            goto IL_D1;
                        default:
                            goto IL_D6;
                    }
                    break;
            }
            result = 10;
            return result;
        IL_BD:
            result = 11;
            return result;
        IL_C2:
            result = 12;
            return result;
        IL_C7:
            result = 13;
            return result;
        IL_CC:
            result = 14;
            return result;
        IL_D1:
            result = 15;
            return result;
        IL_D6:
            result = -1;
            return result;
        }

        public static byte[] HexStringToBytes(string hex)
        {
            MemoryStream memoryStream = new MemoryStream();
            for (int i = 0; i < hex.Length; i++)
            {
                bool flag = i + 1 < hex.Length;
                if (flag)
                {
                    bool flag2 = SoftBasic.GetHexCharIndex(hex[i]) >= 0 && SoftBasic.GetHexCharIndex(hex[i + 1]) >= 0;
                    if (flag2)
                    {
                        memoryStream.WriteByte((byte)(SoftBasic.GetHexCharIndex(hex[i]) * 16 + SoftBasic.GetHexCharIndex(hex[i + 1])));
                        i++;
                    }
                }
            }
            byte[] result = memoryStream.ToArray();
            memoryStream.Dispose();
            return result;
        }

        public static byte[] BytesReverseByWord(byte[] inBytes)
        {
            bool flag = inBytes == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                bool flag2 = inBytes.Length == 0;
                if (flag2)
                {
                    result = new byte[0];
                }
                else
                {
                    byte[] array = SoftBasic.ArrayExpandToLengthEven<byte>(inBytes.CopyArray<byte>());
                    for (int i = 0; i < array.Length / 2; i++)
                    {
                        byte b = array[i * 2];
                        array[i * 2] = array[i * 2 + 1];
                        array[i * 2 + 1] = b;
                    }
                    result = array;
                }
            }
            return result;
        }

        public static string GetAsciiStringRender(byte[] content)
        {
            bool flag = content == null;
            string result;
            if (flag)
            {
                result = string.Empty;
            }
            else
            {
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i < content.Length; i++)
                {
                    bool flag2 = content[i] < 32;
                    if (flag2)
                    {
                        stringBuilder.Append(string.Format("\\{0:X2}", content[i]));
                    }
                    else
                    {
                        stringBuilder.Append((char)content[i]);
                    }
                }
                result = stringBuilder.ToString();
            }
            return result;
        }

        public static byte[] BytesToAsciiBytes(byte[] inBytes)
        {
            return Encoding.ASCII.GetBytes(SoftBasic.ByteToHexString(inBytes));
        }

        public static byte[] AsciiBytesToBytes(byte[] inBytes)
        {
            return SoftBasic.HexStringToBytes(Encoding.ASCII.GetString(inBytes));
        }

        public static byte[] BuildAsciiBytesFrom(byte value)
        {
            return Encoding.ASCII.GetBytes(value.ToString("X2"));
        }

        public static byte[] BuildAsciiBytesFrom(short value)
        {
            return Encoding.ASCII.GetBytes(value.ToString("X4"));
        }

        public static byte[] BuildAsciiBytesFrom(ushort value)
        {
            return Encoding.ASCII.GetBytes(value.ToString("X4"));
        }

        public static byte[] BuildAsciiBytesFrom(uint value)
        {
            return Encoding.ASCII.GetBytes(value.ToString("X8"));
        }

        public static byte[] BuildAsciiBytesFrom(byte[] value)
        {
            byte[] array = new byte[value.Length * 2];
            for (int i = 0; i < value.Length; i++)
            {
                SoftBasic.BuildAsciiBytesFrom(value[i]).CopyTo(array, 2 * i);
            }
            return array;
        }

        private static byte GetDataByBitIndex(int offset)
        {
            byte result;
            switch (offset)
            {
                case 0:
                    result = 1;
                    break;
                case 1:
                    result = 2;
                    break;
                case 2:
                    result = 4;
                    break;
                case 3:
                    result = 8;
                    break;
                case 4:
                    result = 16;
                    break;
                case 5:
                    result = 32;
                    break;
                case 6:
                    result = 64;
                    break;
                case 7:
                    result = 128;
                    break;
                default:
                    result = 0;
                    break;
            }
            return result;
        }

        public static bool BoolOnByteIndex(byte value, int offset)
        {
            byte dataByBitIndex = SoftBasic.GetDataByBitIndex(offset);
            return (value & dataByBitIndex) == dataByBitIndex;
        }

        public static byte SetBoolOnByteIndex(byte byt, int offset, bool value)
        {
            byte dataByBitIndex = SoftBasic.GetDataByBitIndex(offset);
            byte result;
            if (value)
            {
                result = (byte)(byt | dataByBitIndex);
            }
            else
            {
                result = (byte)(byt & ~dataByBitIndex);
            }
            return result;
        }

        public static byte[] BoolArrayToByte(bool[] array)
        {
            bool flag = array == null;
            byte[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                int num = (array.Length % 8 == 0) ? (array.Length / 8) : (array.Length / 8 + 1);
                byte[] array2 = new byte[num];
                for (int i = 0; i < array.Length; i++)
                {
                    bool flag2 = array[i];
                    if (flag2)
                    {
                        byte[] expr_44_cp_0 = array2;
                        int expr_44_cp_1 = i / 8;
                        expr_44_cp_0[expr_44_cp_1] += SoftBasic.GetDataByBitIndex(i % 8);
                    }
                }
                result = array2;
            }
            return result;
        }

        public static bool[] ByteToBoolArray(byte[] InBytes, int length)
        {
            bool flag = InBytes == null;
            bool[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                bool flag2 = length > InBytes.Length * 8;
                if (flag2)
                {
                    length = InBytes.Length * 8;
                }
                bool[] array = new bool[length];
                for (int i = 0; i < length; i++)
                {
                    array[i] = SoftBasic.BoolOnByteIndex(InBytes[i / 8], i % 8);
                }
                result = array;
            }
            return result;
        }

        public static bool[] ByteToBoolArray(byte[] InBytes)
        {
            return (InBytes == null) ? null : SoftBasic.ByteToBoolArray(InBytes, InBytes.Length * 8);
        }

        public static T[] ArrayRemoveDouble<T>(T[] value, int leftLength, int rightLength)
        {
            bool flag = value == null;
            T[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                bool flag2 = value.Length <= leftLength + rightLength;
                if (flag2)
                {
                    result = new T[0];
                }
                else
                {
                    T[] array = new T[value.Length - leftLength - rightLength];
                    Array.Copy(value, leftLength, array, 0, array.Length);
                    result = array;
                }
            }
            return result;
        }

        public static T[] ArrayRemoveBegin<T>(T[] value, int length)
        {
            return SoftBasic.ArrayRemoveDouble<T>(value, length, 0);
        }

        public static T[] ArrayRemoveLast<T>(T[] value, int length)
        {
            return SoftBasic.ArrayRemoveDouble<T>(value, 0, length);
        }

        public static T[] ArraySelectMiddle<T>(T[] value, int index, int length)
        {
            bool flag = value == null;
            T[] result;
            if (flag)
            {
                result = null;
            }
            else
            {
                T[] array = new T[Math.Min(value.Length, length)];
                Array.Copy(value, index, array, 0, array.Length);
                result = array;
            }
            return result;
        }

        public static T[] ArraySelectBegin<T>(T[] value, int length)
        {
            T[] array = new T[Math.Min(value.Length, length)];
            bool flag = array.Length != 0;
            if (flag)
            {
                Array.Copy(value, 0, array, 0, array.Length);
            }
            return array;
        }

        public static T[] ArraySelectLast<T>(T[] value, int length)
        {
            T[] array = new T[Math.Min(value.Length, length)];
            Array.Copy(value, value.Length - length, array, 0, array.Length);
            return array;
        }

        public static T[] SpliceArray<T>(params T[][] arrays)
        {
            int num = 0;
            for (int i = 0; i < arrays.Length; i++)
            {
                T[] expr_0B = arrays[i];
                bool flag = expr_0B != null && expr_0B.Length != 0;
                if (flag)
                {
                    num += arrays[i].Length;
                }
            }
            int num2 = 0;
            T[] array = new T[num];
            for (int j = 0; j < arrays.Length; j++)
            {
                T[] expr_4A = arrays[j];
                bool flag2 = expr_4A != null && expr_4A.Length != 0;
                if (flag2)
                {
                    arrays[j].CopyTo(array, num2);
                    num2 += arrays[j].Length;
                }
            }
            return array;
        }

        public static string[] SpliceStringArray(string first, string[] array)
        {
            List<string> list = new List<string>();
            list.Add(first);
            list.AddRange(array);
            return list.ToArray();
        }

        public static string[] SpliceStringArray(string first, string second, string[] array)
        {
            List<string> list = new List<string>();
            list.Add(first);
            list.Add(second);
            list.AddRange(array);
            return list.ToArray();
        }

        public static string[] SpliceStringArray(string first, string second, string third, string[] array)
        {
            List<string> list = new List<string>();
            list.Add(first);
            list.Add(second);
            list.Add(third);
            list.AddRange(array);
            return list.ToArray();
        }

        //public static object DeepClone(object oringinal)
        //{
        //    object result;
        //    using (MemoryStream memoryStream = new MemoryStream())
        //    {
        //        BinaryFormatter binaryFormatter = new BinaryFormatter
        //        {
        //            Context = new StreamingContext(StreamingContextStates.Clone)
        //        };
        //        binaryFormatter.Serialize(memoryStream, oringinal);
        //        memoryStream.Position = 0L;
        //        result = binaryFormatter.Deserialize(memoryStream);
        //    }
        //    return result;
        //}

        public static string GetUniqueStringByGuidAndRandom()
        {
            Random random = new Random();
            return Guid.NewGuid().ToString("N") + random.Next(1000, 10000).ToString();
        }
    }
}
